home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / BTCLASS.ZIP / BTCLASS@.EXE / TUTOR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-11  |  29.5 KB  |  1,309 lines

  1. /*//////////////////////////////////////////////////////////////////////////
  2. ///            ___                                                       ///
  3. ///          /_____\                                                     ///
  4. ///         |       |                 Copyright (c) 1991                 ///
  5. ///         |   R   |                                                    ///
  6. ///     ----|_______|----                     by                         ///
  7. ///   /------/ | | \------\                                              ///
  8. ///  |       | | | |       |      --  Object Resource Group  --          ///
  9. ///  |   O   | | | |   G   |                                             ///
  10. ///  |       |/   \|       |          4323 Brown Suite 249               ///
  11. ///   -------       -------            Dallas,  TX  75219                ///
  12. ///   Object Resource Group                                              ///
  13. ///                                      (214) 528-2745                  ///
  14. ///                                                                      ///
  15. ///                                    All Rights Reserved.              ///
  16. ///                                                                      ///
  17. //////////////////////////////////////////////////////////////////////////*/
  18.  
  19.  
  20. #include <iostream.h>
  21. #include <iomanip.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include <conio.h>
  25.  
  26. #include "btdset.hpp"
  27. #include "btskey.hpp"
  28. #include "btdef.hpp"
  29. #include "bttran.hpp"
  30. #include "tutor.hpp"
  31.  
  32. int CreateDataSets(void);
  33. int CreatePerson();
  34. int CreateOrder();
  35. int CreateOrderItem();
  36. int CreateItem();
  37. int MainMenu();
  38.  
  39.  
  40. //
  41. // main()
  42. //
  43. //    returns  - status
  44. //     synopsis - creates all databases that currently do not exist
  45. //           runs main menu
  46. //
  47. int main()
  48.    {
  49.    int status = 0;
  50.  
  51.  
  52.    // set cout's behavior
  53.    cout << setprecision(2) << setiosflags(ios::fixed);
  54.  
  55.    // create the datasets if they do not exist
  56.    status = CreateDataSets();
  57.  
  58.    if (!status)
  59.       {
  60.       // run main menu
  61.       status = MainMenu();
  62.       }
  63.  
  64.  
  65.    return status;
  66.    }
  67.  
  68.  
  69.  
  70. //
  71. // CreateDataSets(void)
  72. //
  73. //    returns  - status
  74. //     synopsis - tries to creates each dataset
  75. //
  76. int CreateDataSets(void)
  77.    {
  78.    // create all the databases
  79.    int status = 0;
  80.  
  81.    if ( (status = CreatePerson()) == 0 &&
  82.     (status = CreateOrder()) == 0 &&
  83.     (status = CreateOrderItem()) == 0 )
  84.       status = CreateItem();
  85.  
  86.    return status;
  87.    }
  88.  
  89.  
  90. //
  91. // CreatePerson(void)
  92. //
  93. //    returns  - status
  94. //     synopsis - defines the size of the dataset
  95. //           defines the keys
  96. //           sets the alternate collating sequence
  97. //           creates the dataset
  98. //
  99. int CreatePerson(void)
  100.    {
  101.    int status = 0;
  102.  
  103.    BT_Def fileDef(sizeof(Person), 0);
  104.  
  105.    ///// Define the Keys /////
  106.  
  107.    // key 0 is an AUTOINCREMENT key
  108.    // key 1 is a MODIFIABLE, ZSTRING key that uses UPPER.ALT as
  109.    //        an alternate collating sequence
  110.    //
  111.    // Note that both keys have only one (1) segment
  112.    //
  113.    if ( (status = fileDef.AddFinalKeySegment(1, 4, BKEY_EXTENDED,
  114.                          BTYPE_AUTOINCREMENT)) == 0 &&
  115.     (status = fileDef.AddFinalKeySegment(5, 26, BKEY_EXTENDED+
  116.                             BKEY_MODIFIABLE+
  117.                             BKEY_ALT_SEQUENCE,
  118.                          BTYPE_ZSTRING)) == 0 )
  119.       {
  120.       // set alternate collating sequence
  121.       // to the standard UPPER.ALT
  122.       fileDef.SetUpperAlt();
  123.  
  124.       // This actually creates the dataset.
  125.       // The '-1' causes the method to return an error if
  126.       // the file currently exists.  A '0' or no value
  127.       // would allow the file to be overwritten.
  128.       status = fileDef.CreateBtrieve("person.tbt", -1);
  129.       }
  130.  
  131.  
  132.    // ignore file exists error
  133.    if (status == BSTAT_EXISTS) status = 0;
  134.  
  135.    return(status);
  136.    }
  137.  
  138.  
  139.  
  140. //
  141. // CreateOrder(void)
  142. //
  143. //    returns  - status
  144. //     synopsis - defines the size of the dataset
  145. //           defines the keys
  146. //           creates the dataset
  147. //
  148. int CreateOrder(void)
  149.    {
  150.    int status = 0;
  151.  
  152.    BT_Def fileDef(sizeof(Order), 0);
  153.  
  154.    ///// Define the Keys /////
  155.  
  156.    // key 0 is an NON-MODIFIABLE, NON_DUPLICATABLE ZSTRING
  157.    // key 1 is a MANUAL key with two (2) segments
  158.    //    Segment 1 is a ZSTRING that ALLOWS DUPLICATES
  159.    //    Segment 2 is a UNSIGNED that allows DUPLICATES
  160.    //
  161.    if ( (status = fileDef.AddFinalKeySegment(1, 10, BKEY_EXTENDED,
  162.                             BTYPE_ZSTRING)) == 0 &&
  163.     (status = fileDef.AddKeySegment(15, 8, BKEY_EXTENDED+
  164.                            BKEY_DUPLICATE+
  165.                            BKEY_MANUAL,
  166.                            BTYPE_ZSTRING)) == 0 &&
  167.     (status = fileDef.AddFinalKeySegment(23, 2, BKEY_EXTENDED+
  168.                             BKEY_DUPLICATE+
  169.                             BKEY_MANUAL,
  170.                             BTYPE_UNSIGNED)) == 0 )
  171.       {
  172.       ///// This actually creates the dataset /////
  173.       status = fileDef.CreateBtrieve("order.tbt", -1);
  174.       }
  175.  
  176.  
  177.    // ignore file exists error
  178.    if (status == BSTAT_EXISTS) status = 0;
  179.  
  180.    return(status);
  181.    }
  182.  
  183.  
  184. //
  185. // CreateOrderItem(void)
  186. //
  187. //    returns  - status
  188. //     synopsis - defines the size of the dataset
  189. //           defines the keys
  190. //           creates the dataset
  191. //
  192. int CreateOrderItem(void)
  193.    {
  194.    int status = 0;
  195.  
  196.    BT_Def fileDef(sizeof(OrderItem), 0);
  197.  
  198.  
  199.    ///// Define the Keys /////
  200.  
  201.    if ( (status = fileDef.AddFinalKeySegment(1, 10, BKEY_EXTENDED+
  202.                             BKEY_DUPLICATE,
  203.                             BTYPE_ZSTRING)) == 0 )
  204.       {
  205.       ///// This actually creates the dataset /////
  206.       status = fileDef.CreateBtrieve("o_item.tbt", -1);
  207.       }
  208.  
  209.  
  210.    // ignore file exists error
  211.    if (status == BSTAT_EXISTS) status = 0;
  212.  
  213.    return(status);
  214.    }
  215.  
  216.  
  217. //
  218. // CreateItem(void)
  219. //
  220. //    returns  - status
  221. //     synopsis - defines the size of the dataset
  222. //           defines the keys
  223. //           creates the dataset
  224. //
  225. int CreateItem(void)
  226.    {
  227.    int status = 0;
  228.  
  229.    BT_Def fileDef(sizeof(Item), 0);
  230.  
  231.  
  232.    ///// Define the Keys /////
  233.  
  234.    if ( (status = fileDef.AddFinalKeySegment(1, 2, BKEY_EXTENDED,
  235.                          BTYPE_UNSIGNED)) == 0 )
  236.       {
  237.       ///// This actually creates the dataset /////
  238.       status = fileDef.CreateBtrieve("item.tbt", -1);
  239.       }
  240.  
  241.  
  242.    // ignore file exists error
  243.    if (status == BSTAT_EXISTS) status = 0;
  244.  
  245.    return(status);
  246.    }
  247.  
  248.  
  249. //
  250. // MainMenu(void)
  251. //
  252. //    returns  - status
  253. //     synopsis - loop
  254. //              display choices
  255. //              allow user to process a selection
  256. //           until user is done
  257. //
  258. int MainMenu()
  259.    {
  260.  
  261.    int status=0;
  262.    char choice = ' ';
  263.  
  264.    while (!status && choice != '9')
  265.       {
  266.       cout << "\n\n";
  267.       cout << "          Main Menu\n";
  268.       cout << "-------------------------------\n";
  269.       cout << "\n";
  270.       cout << "  1) - Maintain People\n";
  271.       cout << "  2) - Maintain Orders\n";
  272.       cout << "  3) - Maintain Items\n";
  273.       cout << "\n";
  274.       cout << "  9) - Quit\n";
  275.       cout << "\n";
  276.       cout << "Choice --> "  << flush;
  277.  
  278.       choice  = getch();
  279.       cout << choice;
  280.  
  281.       switch (choice)
  282.      {
  283.      case '1':
  284.         {
  285.         // creating an instance of a dataset causes the
  286.         // file (or files) associated with it to be
  287.         // opened
  288.         PersonDataSet personDataSet;
  289.         status = personDataSet.Menu();
  290.         break;
  291.         }    // out of scope - file is closed automatically
  292.  
  293.      case '2':
  294.         {
  295.         OrderDataSet orderDataSet;
  296.         status = orderDataSet.Menu();
  297.         break;
  298.         }    // out of scope - file is closed automatically
  299.  
  300.      case '3':
  301.         {
  302.         ItemDataSet itemDataSet;
  303.         status = itemDataSet.Menu();
  304.         break;
  305.         }    // out of scope - file is closed automatically
  306.  
  307.  
  308.      default: break;
  309.      }
  310.       }
  311.  
  312.    return status;
  313.    }
  314.  
  315.  
  316.  
  317. //
  318. // PersonDataSet::Menu(void)
  319. //
  320. //    returns  - status
  321. //     synopsis - loop
  322. //              display choices
  323. //              allow user to process a selection
  324. //           until user is done
  325. //
  326. int PersonDataSet::Menu()
  327.    {
  328.    int status = Status();
  329.    char choice = ' ';
  330.  
  331.    while (!status && choice != '9')
  332.       {
  333.       cout << "\n\n";
  334.       cout << "          Person Menu\n";
  335.       cout << "-------------------------------\n";
  336.       cout << "\n";
  337.       cout << "  1) - Add A Person\n";
  338.       cout << "  2) - Modify a Person\n";
  339.       cout << "  3) - List People\n";
  340.       cout << "\n";
  341.       cout << "  9) - Quit\n";
  342.       cout << "\n";
  343.       cout << "Choice --> " << flush;
  344.  
  345.       choice  = getch();
  346.       cout << choice;
  347.  
  348.       switch (choice)
  349.      {
  350.      case '1':
  351.          status = Add();
  352.          break;
  353.      case '2':
  354.          status = Modify();
  355.          break;
  356.      case '3':
  357.          status = List();
  358.          break;
  359.      default: break;
  360.      }
  361.       }
  362.  
  363.    return status;
  364.    }
  365.  
  366.  
  367. //
  368. // PersonDataSet::Add(void)
  369. //
  370. //    returns  - status
  371. //     synopsis - allow user to fill in person info
  372. //           get a key for the dataset
  373. //           insert the record via the key
  374. //
  375. int PersonDataSet::Add()
  376.    {
  377.    Person record;
  378.    int status=0;
  379.    char c;
  380.  
  381.    // fill in the record
  382.  
  383.    cout << "\nPerson Name (Last Name, FirstName) -> ";
  384.    cin.getline(record.name, sizeof(record.name));
  385.  
  386.    cout << "\nStreet -> ";
  387.    cin.getline(record.shipAddress.street, sizeof(record.shipAddress.street));
  388.  
  389.    cout << "\nCity -> ";
  390.    cin.getline(record.shipAddress.city, sizeof(record.shipAddress.city));
  391.  
  392.    cout << "\nState -> ";
  393.    cin.getline(record.shipAddress.state, sizeof(record.shipAddress.state));
  394.    strupr(record.shipAddress.state);
  395.    cin.get();    // extract that last char
  396.  
  397.    cout << "\nZip Code -> ";
  398.    cin.getline(record.shipAddress.zip, sizeof(record.shipAddress.zip));
  399.  
  400.    // get a key and add the record based on the key
  401.    // A key is required as btrieve requires a key
  402.    // path for an insert.  Any key will do.
  403.    key = GetKey(0);
  404.    if (key)
  405.       status = key->Insert(&record);
  406.    else
  407.       status = Status();
  408.  
  409.    return status;
  410.    }
  411.  
  412.  
  413.  
  414. //
  415. // PersonDataSet::Modify(void)
  416. //
  417. //    returns  - status
  418. //     synopsis - get user specified person record
  419. //           allow user to update person info
  420. //           update the record via the key
  421. //
  422. int PersonDataSet::Modify()
  423.    {
  424.    Person record, oldRecord;
  425.    int status=0;
  426.    char c;
  427.  
  428.    // fill in the record
  429.  
  430.    cout << "\nPerson Name (LastName, FirstName) -> ";
  431.    cin.getline(oldRecord.name, sizeof(oldRecord.name));
  432.  
  433.    // get the oldRecord by the NAME KEY
  434.    key = GetKey(1);
  435.  
  436.    if (key)
  437.       {
  438.       status = key->GetEqual(oldRecord.name, &oldRecord);
  439.  
  440.       if (!status)
  441.      {
  442.      // important - make a copy so info not entered below will be in
  443.      // the new record
  444.  
  445.      record = oldRecord;
  446.  
  447.      cout << "\nOld Person Name (LastName, FirstName) -> ";
  448.      cout << oldRecord.name;
  449.      cout << "\nNew Person Name (LastName, FirstName) -> ";
  450.      cin.getline(record.name, sizeof(record.name));
  451.  
  452.      cout << "\nOld Street -> ";
  453.      cout <<  oldRecord.shipAddress.street;
  454.      cout << "\nNew Street -> ";
  455.      cin.getline(record.shipAddress.street, sizeof(record.shipAddress.street));
  456.  
  457.      cout << "\nOld City -> ";
  458.      cout << oldRecord.shipAddress.city;
  459.      cout << "\nNew City -> ";
  460.      cin.getline(record.shipAddress.city, sizeof(record.shipAddress.city));
  461.  
  462.      cout << "\nOld State -> ";
  463.      cout << oldRecord.shipAddress.state;
  464.      cout << "\nNew State -> ";
  465.      cin.getline(record.shipAddress.state, sizeof(record.shipAddress.state));
  466.      strupr(record.shipAddress.state);
  467.      if (strlen(record.shipAddress.state) == 2)
  468.         cin.get();    // extract that last char
  469.  
  470.      cout << "\nOld Zip Code -> ";
  471.      cout << oldRecord.shipAddress.zip;
  472.      cout << "\nNew Zip Code -> ";
  473.      cin.getline(record.shipAddress.zip, sizeof(record.shipAddress.zip));
  474.  
  475.      // make sure valid values exist
  476.      if ( !strlen(record.name) )
  477.         strcpy(record.name, oldRecord.name);
  478.  
  479.      if ( !strlen(record.shipAddress.street) )
  480.         strcpy(record.shipAddress.street, oldRecord.shipAddress.street);
  481.  
  482.      if ( !strlen(record.shipAddress.city) )
  483.         strcpy(record.shipAddress.city, oldRecord.shipAddress.city);
  484.  
  485.      if ( !strlen(record.shipAddress.state) )
  486.         strcpy(record.shipAddress.state, oldRecord.shipAddress.state);
  487.  
  488.      if ( !strlen(record.shipAddress.zip) )
  489.         strcpy(record.shipAddress.zip, oldRecord.shipAddress.zip);
  490.  
  491.  
  492.      // update the record - shockingly easy
  493.      status = key->Update(&record);
  494.      if (status)
  495.         cout << "Error " << status << " occurred while updating "
  496.         << record.name << ends;
  497.      }
  498.       else
  499.      {
  500.      if (status == BSTAT_NOTFOUND)
  501.         {
  502.         cout << "Person: " << oldRecord.name << " was not found";
  503.         status = 0;
  504.         }
  505.      else
  506.         cout << "Error " << status << " occurred while searching for "
  507.         << oldRecord.name << ends;
  508.  
  509.      }
  510.       }
  511.    else
  512.       status = Status();
  513.  
  514.  
  515.    return status;
  516.    }
  517.  
  518.  
  519.  
  520. //
  521. // PersonDataSet::List(void)
  522. //
  523. //    returns  - status
  524. //     synopsis - get first person record by NAME key
  525. //           loop
  526. //              print person info
  527. //              get next person record
  528. //           until no more records
  529. //
  530. int PersonDataSet::List()
  531.    {
  532.    // list in name order
  533.    int status = Status();
  534.    Person record;
  535.  
  536.    // get the oldRecord by the NAME KEY
  537.    key = GetKey(1);
  538.  
  539.    if (key)
  540.       {
  541.       status = key->GetFirst(&record);
  542.  
  543.       int count = 0;
  544.       while (!status)
  545.      {
  546.      // done to make the screen look pretty, not
  547.      // particularly necessary
  548.      if (!count || count > 20)
  549.         {
  550.         if (count)
  551.            {
  552.            cout << "Pause --- Hit any key for next screen" << endl;
  553.            getch();
  554.            }
  555.  
  556.         cout << "\n\nPerson File Listing\n";
  557.         cout << "-------------------\n\n";
  558.         count = 0;
  559.         }
  560.  
  561.      cout << record.name << '\n';
  562.      cout << record.shipAddress.street << '\n';
  563.      cout << record.shipAddress.city << ", " << record.shipAddress.state
  564.             << "  " << record.shipAddress.zip << "\n\n";
  565.      count += 5;
  566.  
  567.      // get the next person record
  568.      status = key->GetNext(&record);
  569.      }
  570.       if (status == BSTAT_EOF) status = 0;
  571.       }
  572.    else
  573.       status = Status();
  574.  
  575.  
  576.    return status;
  577.    }
  578.  
  579.  
  580.  
  581. //
  582. // ItemDataSet::Menu(void)
  583. //
  584. //    returns  - status
  585. //     synopsis - loop
  586. //              display choices
  587. //              allow user to process a selection
  588. //           until user is done
  589. //
  590. int ItemDataSet::Menu()
  591.    {
  592.    int status = Status();
  593.    char choice = ' ';
  594.  
  595.    while (!status && choice != '9')
  596.       {
  597.       cout << "\n\n";
  598.       cout << "          Item Menu\n";
  599.       cout << "-------------------------------\n";
  600.       cout << "\n";
  601.       cout << "  1) - Add An Item\n";
  602.       cout << "  2) - Modify an Item\n";
  603.       cout << "  3) - List Items\n";
  604.       cout << "\n";
  605.       cout << "  9) - Quit\n";
  606.       cout << "\n";
  607.       cout << "Choice --> " << flush;
  608.  
  609.       choice  = getch();
  610.       cout << choice << endl;
  611.  
  612.       switch (choice)
  613.      {
  614.      case '1':
  615.          status = Add();
  616.          break;
  617.      case '2':
  618.          status = Modify();
  619.          break;
  620.      case '3':
  621.          status = List();
  622.          break;
  623.      default: break;
  624.      }
  625.       }
  626.  
  627.    return status;
  628.    }
  629.  
  630.  
  631.  
  632. //
  633. // ItemDataSet::Add(void)
  634. //
  635. //    returns  - status
  636. //     synopsis - allow user to fill in item info
  637. //           get a key for the dataset
  638. //           insert the record via the key
  639. //
  640. int ItemDataSet::Add()
  641.    {
  642.    Item record;
  643.    int status=0;
  644.    char c;
  645.  
  646.    // fill in the record
  647.  
  648.    cout << "\nItem Number -> ";
  649.    cin >> record.itemNumber;
  650.    cin.get();        // removes extra \n in stream
  651.  
  652.    cout << "\nDescription -> ";
  653.    cin.getline(record.description, sizeof(record.description));
  654.  
  655.    cout << "\nUnit Cost -> ";
  656.    cin >> record.unitCost;
  657.    cin.get();        // removes extra \n in stream
  658.  
  659.    // get a key and add the record based on the key
  660.    key = GetKey(0);
  661.  
  662.    if (key)
  663.       status = key->Insert(&record);
  664.    else
  665.       status = Status();
  666.  
  667.    return status;
  668.    }
  669.  
  670.  
  671.  
  672. //
  673. // ItemDataSet::Modify(void)
  674. //
  675. //    returns  - status
  676. //     synopsis - get user specified item record
  677. //           allow user to update item info
  678. //           update the record via the key
  679. //
  680. int ItemDataSet::Modify()
  681.    {
  682.    Item record, oldRecord;
  683.    int status=0;
  684.    char c;
  685.  
  686.    // fill in the record
  687.  
  688.    cout << "\nItem Number -> ";
  689.    cin >> oldRecord.itemNumber;
  690.    cin.get();        // removes extra \n in stream
  691.  
  692.    // get the oldRecord by the ITEM KEY
  693.    key = GetKey(0);
  694.  
  695.    if (key)
  696.       {
  697.       status = key->GetEqual(&oldRecord.itemNumber, &oldRecord);
  698.  
  699.       if (!status)
  700.      {
  701.      // important - make a copy so info not entered below will be in
  702.      // the new record
  703.  
  704.      record = oldRecord;
  705.  
  706.      cout << "\nOld Description -> ";
  707.      cout << oldRecord.description;
  708.      cout << "\nNew Description -> ";
  709.      cin.getline(record.description, sizeof(record.description));
  710.  
  711.      cout << "\nOld Unit Cost -> ";
  712.      cout << setprecision(2) << oldRecord.unitCost;
  713.      cout << "\nNew Unit Cost -> ";
  714.      cin >> record.unitCost;
  715.      cin.get();        // removes extra \n in stream
  716.  
  717.      // make sure valid values exist
  718.      if ( !strlen(record.description) )
  719.         strcpy(record.description, oldRecord.description);
  720.  
  721.      if ( record.unitCost == 0.0 )
  722.         record.unitCost = oldRecord.unitCost;
  723.  
  724.      // update the record - shockingly easy
  725.      status = key->Update(&record);
  726.      if (status)
  727.         cout << "Error " << status << " occurred while updating ";
  728.         cout <<  record.itemNumber;
  729.      }
  730.       else
  731.      {
  732.      if (status == BSTAT_NOTFOUND)
  733.         {
  734.         cout << "Item: " << oldRecord.itemNumber << " was not found";
  735.  
  736.         status = 0;
  737.         }
  738.      else
  739.         cout << "Error " << status << " occurred while searching for ";
  740.         cout << oldRecord.itemNumber;
  741.      }
  742.       }
  743.    else
  744.       status = Status();
  745.  
  746.  
  747.    return status;
  748.    }
  749.  
  750.  
  751.  
  752. //
  753. // ItemDataSet::List(void)
  754. //
  755. //    returns  - status
  756. //     synopsis - get first item record by key
  757. //           loop
  758. //              print item info
  759. //              get next item record
  760. //           until no more records
  761. //
  762. int ItemDataSet::List()
  763.    {
  764.    // list in name order
  765.    int status = 0;
  766.    Item record;
  767.  
  768.    // get the oldRecord by the NUMBER KEY
  769.    key = GetKey(0);
  770.  
  771.    if (key)
  772.       {
  773.       status = key->GetFirst(&record);
  774.  
  775.       int count = 0;
  776.       while (!status)
  777.      {
  778.      if (!count || count > 20)
  779.         {
  780.         if (count)
  781.            {
  782.            cout << "Pause --- Hit any key for next screen" << endl;
  783.            getch();
  784.            }
  785.  
  786.         cout << "\n\nItem File Listing\n";
  787.         cout << "-------------------\n\n";
  788.         count = 0;
  789.         }
  790.  
  791.      cout << record.itemNumber << " - " << record.description;
  792.      cout << " @ " << setprecision(2) << record.unitCost << " each\n";
  793.      count++;
  794.      status = key->GetNext(&record);
  795.      }
  796.       if (status == BSTAT_EOF) status = 0;
  797.       }
  798.    else
  799.       status = Status();
  800.  
  801.  
  802.    return status;
  803.    }
  804.  
  805.  
  806.  
  807.  
  808. //
  809. // OrderDataSet::Menu(void)
  810. //
  811. //    returns  - status
  812. //     synopsis - loop
  813. //              display choices
  814. //              allow user to process a selection
  815. //           until user is done
  816. //
  817. int OrderDataSet::Menu()
  818.    {
  819.    int status = Status();
  820.    char choice = ' ';
  821.  
  822.    while (!status && choice != '9')
  823.       {
  824.       cout << "\n\n";
  825.       cout << "          Order Menu\n";
  826.       cout << "-------------------------------\n";
  827.       cout << "\n";
  828.       cout << "  1) - Add An Order\n";
  829.       cout << "  2) - Modify an Order\n";
  830.       cout << "  3) - List All Orders\n";
  831.       cout << "  4) - Print an Invoice\n";
  832.       cout << "\n";
  833.       cout << "  9) - Quit\n";
  834.       cout << "\n";
  835.       cout << "Choice --> " << flush;
  836.  
  837.       choice  = getch();
  838.       cout << choice << "\n";
  839.  
  840.       switch (choice)
  841.      {
  842.      case '1':
  843.          status = Add();
  844.          break;
  845.      case '2':
  846.          status = Modify();
  847.          break;
  848.      case '3':
  849.          status = List();
  850.          break;
  851.      case '4':
  852.          status = PrintOne();
  853.          break;
  854.      default: break;
  855.      }
  856.       }
  857.  
  858.    return status;
  859.    }
  860.  
  861.  
  862.  
  863. //
  864. // OrderDataSet::Add(void)
  865. //
  866. //    returns  - status
  867. //     synopsis - start a transaction
  868. //           allow user to fill in order info
  869. //           validate the person
  870. //           loop
  871. //              add an order item
  872. //           until user is finished
  873. //           get a key for the dataset
  874. //           insert the record via the key
  875. //           end the transaction
  876. //
  877. int OrderDataSet::Add()
  878.    {
  879.    Order record;
  880.    int status=0;
  881.    char c;
  882.  
  883.  
  884.    // Because we will update multiple datasets, this is a good
  885.    // opportunity to use a transaction.  NOTE - Never use a transaction
  886.    // in this manner (as files are locked while waiting on the user
  887.    // input) in a network environment unless one desire to stop up the
  888.    // system (or unless one is writing a simple tutorial).  Instead, buffer
  889.    // information and use the transaction only when accessing the files
  890.  
  891.    BT_Transaction transaction;
  892.  
  893.  
  894.    if (transaction.Status())
  895.       return status;        // problem - get out immediately
  896.  
  897.  
  898.    // fill in the record
  899.  
  900.    cout << "\nOrder Number -> ";
  901.    cin.getline(record.number, sizeof(record.number));
  902.  
  903.  
  904.    Person person;
  905.    do
  906.       {
  907.       cout << "\nPerson's Name (Last Name, First) -> ";
  908.       cin.getline(person.name, sizeof(person.name));
  909.  
  910.       if (strlen(person.name))
  911.      {
  912.      // check to see if name is legit
  913.      personDS.key = personDS.GetKey(1);
  914.      status = personDS.key->GetEqual(person.name, &person);
  915.      if (status)
  916.         {
  917.         if (status == BSTAT_NOTFOUND)
  918.            cout << "Person: " << person.name
  919.             << " was not found - please reenter" << flush;
  920.  
  921.         else
  922.            break;
  923.         }
  924.      }
  925.       else
  926.      person.id = 0;
  927.       } while (status);
  928.  
  929.    if (!status && person.id)
  930.       {
  931.       record.personID = person.id;
  932.  
  933.       // lousy method but, hey, this is a simple tutorial example
  934.       // a real OOProgrammer would have some nifty date class
  935.       cout << "\nPlease enter date (YYMMDD) -> ";
  936.       cin.getline(record.dateOrdered, 7);
  937.       cin.get();        // removes extra \n in stream
  938.  
  939.  
  940.       // check if prepaid
  941.       cout << "\nHas person paid yet (Y/N) -> ";
  942.       char answer;
  943.       cin.get(answer);
  944.       cin.get();
  945.       if (toupper(answer) == 'Y')
  946.      record.paidFlag = Boolean((answer == 'Y') ? True : False);
  947.  
  948.  
  949.       // get all order items for the order
  950.       do
  951.      {
  952.      status = orderItemDS.Add(record.number);
  953.      } while (!status);    // BSTAT_EOF is returned when nothing entered
  954.  
  955.       // check if user was just requesting to quick
  956.       if (status == BSTAT_EOF) status = 0;
  957.  
  958.       if (!status)
  959.      {
  960.      // get a key and add the record based on the key
  961.      key = GetKey(0);
  962.  
  963.      if (key)
  964.         status = key->Insert(&record);
  965.      else
  966.         status = Status();
  967.      }
  968.  
  969.       }
  970.  
  971.    // if everything is good - commit to disk
  972.    if (!status)
  973.       status = transaction.Commit();
  974.  
  975.    return status;
  976.    }
  977.  
  978.  
  979.  
  980. //
  981. // OrderDataSet::Modify(void)
  982. //
  983. //    returns  - status
  984. //     synopsis - get user specified order record
  985. //           allow user to update paid status
  986. //           update the record via the key
  987. //
  988. int OrderDataSet::Modify()
  989.    {
  990.    Order record, oldRecord;
  991.    int status=0;
  992.    char c;
  993.  
  994.    // fill in the record
  995.  
  996.    cout << "\nOrder Number -> ";
  997.    cin.getline(oldRecord.number, sizeof(oldRecord.number));
  998.  
  999.    // get the oldRecord by the order number key
  1000.    key = GetKey(0);
  1001.  
  1002.    if (key)
  1003.       {
  1004.       status = key->GetEqual(oldRecord.number, &oldRecord);
  1005.  
  1006.       if (!status)
  1007.      {
  1008.      // important - make a copy so info not entered below will be in
  1009.      // the new record
  1010.  
  1011.      record = oldRecord;
  1012.  
  1013.      // check if prepaid
  1014.      cout << "\nHas person paid yet (Y/N) -> ";
  1015.      char answer;
  1016.      cin.get(answer);
  1017.      cin.get();
  1018.      if (toupper(answer) == 'Y')
  1019.         record.paidFlag = Boolean((answer == 'Y') ? True : False);
  1020.  
  1021.      // update the record - shockingly easy
  1022.      status = key->Update(&record);
  1023.      if (status)
  1024.         {
  1025.         cout << "Error " << status << " occurred while updating ";
  1026.         cout << record.number;
  1027.         }
  1028.      }
  1029.       else
  1030.      {
  1031.      if (status == BSTAT_NOTFOUND)
  1032.         {
  1033.         cout << "Order: " << oldRecord.number << " was not found";
  1034.         status = 0;
  1035.         }
  1036.      else
  1037.         {
  1038.         cout << "Error " << status << " occurred while searching for ";
  1039.         cout << oldRecord.number;
  1040.         }
  1041.      }
  1042.       }
  1043.    else
  1044.       status = Status();
  1045.  
  1046.  
  1047.    return status;
  1048.    }
  1049.  
  1050.  
  1051.  
  1052. //
  1053. // OrderDataSet::PrintOne(void)
  1054. //
  1055. //    returns  - status
  1056. //     synopsis - get user specified order record
  1057. //           print order info
  1058. //           loop
  1059. //              print each item's information
  1060. //           until no more items
  1061. //           print summary information
  1062. //
  1063. int OrderDataSet::PrintOne()
  1064.    {
  1065.    Order record;
  1066.    int status=0;
  1067.    char c;
  1068.  
  1069.    // fill in the record
  1070.  
  1071.    cout << "\n\nOrder Number -> ";
  1072.    cin.getline(record.number, sizeof(record.number));
  1073.  
  1074.    // get the order record
  1075.    key = GetKey(0);
  1076.  
  1077.    if (key)
  1078.       {
  1079.       status = key->GetEqual(record.number, &record);
  1080.  
  1081.       if (!status)
  1082.      {
  1083.      // print order
  1084.      cout << "Purchase Order Number: " << record.number << endl;
  1085.      cout << "Date of Order: " <<  record.dateOrdered << endl << endl;
  1086.  
  1087.      // get person and address
  1088.      cout << "Ship to: ";
  1089.      personDS.key = personDS.GetKey(0);
  1090.      Person person;
  1091.      if (personDS.key->GetEqual(&record.personID, &person))
  1092.         {
  1093.         // not found
  1094.         cout << "UKNOWN PERSON\n\n\n\n";
  1095.         }
  1096.      else
  1097.         {
  1098.         cout << person.name << endl;
  1099.         cout << "         " << person.shipAddress.street << endl;
  1100.         cout << "         " << person.shipAddress.city << ", ";
  1101.         cout << person.shipAddress.state << "  ";
  1102.         cout << person.shipAddress.zip << endl << endl;
  1103.         }
  1104.  
  1105.      // header line for items in order
  1106.      cout << " Item #            Description               Quantity  Unit Cost  Total Cost\n";
  1107.      cout << " ------ ----------------------------------- ---------- ---------- ----------\n";
  1108.      cout << "\n";
  1109.  
  1110.      // loop for each item
  1111.      OrderItem orderItem;
  1112.      Item item;
  1113.  
  1114.      orderItemDS.key = orderItemDS.GetKey(0);
  1115.      status = orderItemDS.key->GetGreaterEqual(record.number, &orderItem);
  1116.      if ( !status && !(strcmp(orderItem.orderNumber, record.number)) )
  1117.         {
  1118.         double grandTotal = 0.0;
  1119.  
  1120.         do
  1121.            {
  1122.            cout << " " << setw(6) << orderItem.itemNumber << " ";
  1123.  
  1124.            // get description
  1125.            orderItemDS.itemDS.key = orderItemDS.itemDS.GetKey(0);
  1126.            if (orderItemDS.itemDS.key->GetEqual(&orderItem.itemNumber, &item))
  1127.           strcpy(item.description, "UNKNOWN");
  1128.  
  1129.            double totCost = orderItem.purchaseCost * orderItem.quantity;
  1130.            grandTotal += totCost;
  1131.        //    printf("%-35s %10.2f %10.2f %10.2f\n",
  1132.            cout << setiosflags(ios::left) << setw(35)
  1133.             << item.description << " ";
  1134.            cout << resetiosflags(ios::left) << setw(10)
  1135.             << orderItem.quantity << " ";
  1136.            cout << setw(10) << orderItem.purchaseCost << " ";
  1137.            cout << setw(10) << totCost << endl;
  1138.  
  1139.            status = orderItemDS.key->GetNext(&orderItem);
  1140.            } while (!status && !(strcmp(orderItem.orderNumber, record.number)));
  1141.  
  1142.        //printf("\n                                          "
  1143.        //       "Grand Total ->%11.2f\n\n", grandTotal);
  1144.         cout << "Grand Total ->" << grandTotal << "\n\n";
  1145.         }
  1146.      else
  1147.         {
  1148.         cout <<"                            NO ITEMS FOUND" << endl;
  1149.         }
  1150.  
  1151.      if (status == BSTAT_EOF) status = 0;
  1152.      }
  1153.       else
  1154.      {
  1155.      if (status == BSTAT_NOTFOUND)
  1156.         {
  1157.         cout << "Order: " << record.number << " was not found";
  1158.         status = 0;
  1159.         }
  1160.      else
  1161.         cout << "Error " << status << " occurred while searching for "
  1162.         << record.number;
  1163.      }
  1164.       }
  1165.    else
  1166.       status = Status();
  1167.  
  1168.  
  1169.    return status;
  1170.    }
  1171.  
  1172.  
  1173.  
  1174. //
  1175. // OrderDataSet::List(void)
  1176. //
  1177. //    returns  - status
  1178. //     synopsis - get first order record by key
  1179. //           loop
  1180. //              print order info
  1181. //              get next order record
  1182. //           until no more records
  1183. //
  1184. int OrderDataSet::List()
  1185.    {
  1186.    // list in name order
  1187.    int status = Status();
  1188.    Order record;
  1189.  
  1190.    // get the oldRecord by the NUMBER
  1191.    key = GetKey(0);
  1192.  
  1193.    if (key)
  1194.       {
  1195.       status = key->GetFirst(&record);
  1196.  
  1197.       int count = 0;
  1198.       while (!status)
  1199.      {
  1200.      if (!count || count > 20)
  1201.         {
  1202.         if (count)
  1203.            {
  1204.            cout << "Pause --- Hit any key for next screen\n" << flush;
  1205.            getch();
  1206.            }
  1207.  
  1208.         cout << "\n\nPurchase Order File Listing\n";
  1209.         cout <<     "---------------------------\n\n";
  1210.         count = 0;
  1211.         }
  1212.  
  1213.  
  1214.      cout << record.number << " items ordered on " << record.dateOrdered
  1215.         << " by ";
  1216.      // look for person
  1217.      personDS.key = personDS.GetKey(0);
  1218.      Person person;
  1219.      if (personDS.key->GetEqual(&record.personID, &person))
  1220.         {
  1221.         // not found
  1222.         cout << "UKNOWN PERSON\n";
  1223.         }
  1224.      else
  1225.         cout << person.name << endl;
  1226.  
  1227.      count += 1;
  1228.      status = key->GetNext(&record);
  1229.      }
  1230.       if (status == BSTAT_EOF) status = 0;
  1231.       }
  1232.    else
  1233.       status = Status();
  1234.  
  1235.  
  1236.    return status;
  1237.    }
  1238.  
  1239.  
  1240.  
  1241. //
  1242. // OrderItemDataSet::Add(order number)
  1243. //
  1244. //    returns  - status
  1245. //     synopsis - allow user to fill in order item info
  1246. //           get a key for the dataset
  1247. //           insert the record via the key
  1248. //
  1249. int OrderItemDataSet::Add(const char *orderNumber)
  1250.    {
  1251.    OrderItem record;
  1252.    int status=0;
  1253.  
  1254.    strcpy(record.orderNumber, orderNumber);
  1255.  
  1256.    Item item;
  1257.  
  1258.    cout << endl;
  1259.  
  1260.    do
  1261.       {
  1262.       cout << "Enter item number (0 - Quit) -> ";
  1263.       cin >> record.itemNumber;
  1264.       cin.get();
  1265.  
  1266.       if (record.itemNumber)
  1267.      {
  1268.      // validate itemNumber
  1269.      itemDS.key = itemDS.GetKey(0);
  1270.      status = itemDS.key->GetEqual(&record.itemNumber, &item);
  1271.      if (status)
  1272.         {
  1273.         if (status == BSTAT_NOTFOUND)
  1274.            {
  1275.            cout << "Item number: " <<  record.itemNumber
  1276.             << " not found - Please reenter" << endl;
  1277.            }
  1278.         else
  1279.            {
  1280.            cout << "Error " << status << " finding item number: "
  1281.             << record.itemNumber << endl;
  1282.            }
  1283.         }
  1284.      else
  1285.         record.purchaseCost = item.unitCost;
  1286.      }
  1287.       else
  1288.      status = BSTAT_EOF;        // user wants to quit
  1289.  
  1290.       } while (status == BSTAT_NOTFOUND);
  1291.  
  1292.    if (!status)
  1293.       {
  1294.       cout << "Enter quantity to order -> ";
  1295.       cin >> record.quantity;
  1296.       cin.get();
  1297.  
  1298.  
  1299.       // get a key and add the record based on the key
  1300.       key = GetKey(0);
  1301.  
  1302.       if (key)
  1303.      status = key->Insert(&record);
  1304.       else
  1305.      status = Status();
  1306.       }
  1307.    return status;
  1308.    }
  1309.